package com.ksd.web.controller.system;

import java.io.File;
import java.util.*;
import javax.servlet.http.HttpServletResponse;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ksd.common.annotation.Log;
import com.ksd.common.config.PlayControlConfig;
import com.ksd.common.constant.HttpStatus;
import com.ksd.common.core.controller.BaseController;
import com.ksd.common.core.domain.AjaxResult;
import com.ksd.common.core.page.PageDomain;
import com.ksd.common.core.page.TableDataInfo;
import com.ksd.common.core.page.TableSupport;
import com.ksd.common.enums.BusinessType;
import com.ksd.common.utils.DateUtils;
import com.ksd.common.utils.StringUtils;
import com.ksd.common.utils.file.FileUploadUtils;
import com.ksd.common.utils.poi.ExcelUtil;
import com.ksd.common.utils.sql.SqlUtil;
import com.ksd.quartz.util.TaskConstans;
import com.ksd.system.domain.*;
import com.ksd.system.service.*;
import com.ksd.system.service.impl.SysChannelTemplateServiceImpl;
import com.ksd.web.controller.tool.FileUtils;
import com.ksd.web.controller.upload.FileUsingIO;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 频道管理Controller
 * 
 * @author y.wu
 * @date 2025-01-08
 */
@RestController
@RequestMapping("/system/channel")
public class SysChannelController extends BaseController
{
    @Autowired
    private ISysOperLogService sysOperLogService;
    @Autowired
    private ISysChannelTemplateService sysChannelTemplateService;
    @Autowired
    private ISysChannelService sysChannelService;
    @Autowired
    private ISysFreqService sysFreqService;
    @Autowired
    private ISysBoardService sysBoardService;
    /**
     * 查询频道管理列表
     */
    @PreAuthorize("@ss.hasPermi('system:channel:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysChannelTemplate sysChannelTemplate)
    {
        startPage();
        sysChannelTemplate.setStatus(TaskConstans.status_selected);
        List<SysChannelTemplate> sysChannelTemplatesResult = sysChannelTemplateService.selectSysChannelTemplateListByChannelId(sysChannelTemplate);
        logger.info("查询到的已分配频道个数:"+sysChannelTemplatesResult.size()+"=============="+sysChannelTemplate.getChannelId());
        for (SysChannelTemplate channelTemplate : sysChannelTemplatesResult) {
            Long boardIdSelect = channelTemplate.getBoardId();
            String name = channelTemplate.getName();
            if (TaskConstans.boardValue1.equals(boardIdSelect.toString())){
                SysChannel sysChannel = new SysChannel();
                sysChannel.setBoardId(boardIdSelect);
                sysChannel.setName(name);
                SysChannel temp = sysChannelService.selectSysChannelList(sysChannel, SysChannel.table_one).get(0);
                SysFreq freqOne = sysFreqService.selectSysFreqByFreq(temp.getFreq(), SysFreq.table_one);

                channelTemplate.setFreq(temp.getFreq());
                channelTemplate.setBoardStr("直播板卡"+boardIdSelect);
                channelTemplate.setNumber(freqOne.getNumber());
                channelTemplate.setPlayUrl(PlayControlConfig.getChannelUrlStart() +channelTemplate.getIp()+":"+channelTemplate.getPort());
                String formattedNumber = String.format("%02d", channelTemplate.getChannelId());
                channelTemplate.setChannelIdStr(formattedNumber);
            }else if (TaskConstans.boardValue2.equals(boardIdSelect.toString())){

                SysChannel sysChannel = new SysChannel();
                sysChannel.setBoardId(boardIdSelect);
                sysChannel.setName(name);
                SysChannel temp = sysChannelService.selectSysChannelList(sysChannel, SysChannel.table_twice).get(0);
                SysFreq sysFreqTwice = sysFreqService.selectSysFreqByFreq(temp.getFreq(), SysFreq.table_twice);
                channelTemplate.setFreq(temp.getFreq());
                channelTemplate.setBoardStr("直播板卡"+boardIdSelect);
                channelTemplate.setNumber(sysFreqTwice.getNumber());
                channelTemplate.setPlayUrl(PlayControlConfig.getChannelUrlStart() +channelTemplate.getIp()+":"+channelTemplate.getPort());

                String formattedNumber = String.format("%02d", channelTemplate.getChannelId());
                channelTemplate.setChannelIdStr(formattedNumber);
            }else if(TaskConstans.boardValueCustom.equals(boardIdSelect.toString())){
                //自办节目
                String formattedNumber = String.format("%02d", channelTemplate.getChannelId());
                channelTemplate.setChannelIdStr(formattedNumber);
                String urlType = channelTemplate.getUrlType();
                if(urlType.equals("1")){
                    //U盘
                    SysBoard sysBoard = sysBoardService.selectSysBoardById(SysBoard.serviceFileId);
                    channelTemplate.setPlayUrl(sysBoard.getUrl()+channelTemplate.getSourcePath());
                }else if(urlType.equals("2")){
                    //网络
                    channelTemplate.setPlayUrl(channelTemplate.getSourceUrl());
                }
                channelTemplate.setBoardStr("自办节目");
            }
        }
        return getDataTable(sysChannelTemplatesResult);
    }
    /**
     * 获取频道管理详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:channel:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        SysChannelTemplate sysChannelTemplate = sysChannelTemplateService.selectSysChannelTemplateById(id);
//        String logo = sysChannelTemplate.getLogo();
//        SysChannelCustom sysChannelCustom = sysChannelCustomService.selectSysChannelCustomById(Long.valueOf(logo));
//        return success(sysChannelService.selectSysChannelById(id,SysChannel.table_one));
        return AjaxResult.success(sysChannelTemplate);
    }

    /**
     * 新增频道管理
     */
    @PreAuthorize("@ss.hasPermi('system:channel:add')")
    @Log(title = "频道管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysChannelTemplate sysChannelTemplate)
    {

        if (!sysChannelTemplateService.checkNameUnique(sysChannelTemplate)){
            sysOperLogService.insertOperlogError("新增自办节目失败,频道:"+sysChannelTemplate.getName()+" ,该频道名称已存在");
            return error("新增自办节目失败,频道:"+sysChannelTemplate.getName()+" ,该频道名称已存在");
        }
        if (sysChannelTemplate.getUrlType().equals("2")) {
            if (!sysChannelTemplateService.checkSourceUrlUnique(sysChannelTemplate)) {
                sysOperLogService.insertOperlogError("新增自办节目失败,频道:" + sysChannelTemplate.getName() + " ,该源地址已存在");
                return error("新增自办节目失败,频道:" + sysChannelTemplate.getName() + " ,该源地址已存在");
            }
        }
        SysChannelTemplate temp = new SysChannelTemplate();
        temp.setBoardId(-1l);
        temp.setStatus(TaskConstans.status_selected);
        List<SysChannelTemplate> sysChannelTemplates = sysChannelTemplateService.selectSysChannelTemplateList(temp);
        Long newChannelId = 0L;
        if (sysChannelTemplates.size() > 0) {
            Long maxChannelId = sysChannelTemplates.get(sysChannelTemplates.size()-1).getChannelId();
            newChannelId = maxChannelId + 1;
        }else{
            newChannelId = 40L; //自办节目编号从40开始
        }
        sysChannelTemplate.setBoardId(Long.valueOf(TaskConstans.boardValueCustom));
        sysChannelTemplate.setChannelId(newChannelId);
        sysChannelTemplate.setStatus(TaskConstans.status_selected);
        String urlType = sysChannelTemplate.getUrlType();
        if (urlType.equals("1")){
           //U盘 ==>需要将选中的文件上传到nginx的指定位置
            List<String> sourcePath = sysChannelTemplate.getSourcePaths();
            AjaxResult ajaxResult = updateChannelFile(sysChannelTemplate);
            if (StringUtils.isNotNull(ajaxResult) && ajaxResult.isSuccess()){
                File channelFile = (File) ajaxResult.get(AjaxResult.DATA_TAG);
                //将文件上传到nginx的指定位置并入库
                String dataPath = File.separator+"channel_files"+File.separator+ DateUtils.dateTimeNow();
//                String nginxPath = PlayControlConfig.getNginxRootPath()+dataPath+File.separator+channelFile.getName();
//                String mappindPath = PlayControlConfig.getMappingPath()+dataPath+File.separator+channelFile.getName();
                String nginxPath = PlayControlConfig.getDiskNginxRootPath()+dataPath+File.separator+channelFile.getName();
                String mappindPath = PlayControlConfig.getDiskMappingPath()+dataPath+File.separator+channelFile.getName();
                FileUsingIO.moveFile(channelFile.getAbsolutePath(),nginxPath);
                sysChannelTemplate.setSourcePath(mappindPath);
                sysChannelTemplateService.insertSysChannelTemplate(sysChannelTemplate);
                sysOperLogService.insertOperlogSuccess("新增自办节目成功,频道号:"+newChannelId+" ,频道名称:"+sysChannelTemplate.getName()+" ,源文件地址:"+sysChannelTemplate.getSourcePath()+" ,源输出方式:"+sysChannelTemplate.getSourceOut());
            }else{
                return ajaxResult;
            }

        }else if (urlType.equals("2")){
            //网络
            sysChannelTemplateService.insertSysChannelTemplate(sysChannelTemplate);
            sysOperLogService.insertOperlogSuccess("新增自办节目成功,频道号:"+newChannelId+" ,频道名称:"+sysChannelTemplate.getName()+" ,网络节目地址:"+sysChannelTemplate.getSourceUrl()+" ,源输出方式:"+sysChannelTemplate.getSourceOut());
        }
        return success();
    }

    public AjaxResult updateChannelFile(SysChannelTemplate sysChannelTemplate){
        List<String> filePaths = sysChannelTemplate.getSourcePaths();

        Set<String> channelFilePath = new HashSet<>();
        // 统计所有文件数量,该路径已经被算过,只存在具体的文件,没有文件夹
        for (String filePath : filePaths) {
            File directory = new File(filePath);
            if (directory.isDirectory()){
                channelFilePath = findFilesInSubdirectories(directory,channelFilePath);
            }else{
//                if (FileUploadUtils.isAllowedExtension(directory.getName(), TaskConstans.synch_file_name)){
                if (directory.getName().endsWith(upload_channel_file)){
                    //将文件夹下的所有文件都复制上传
                    channelFilePath.add(directory.getAbsolutePath());
                }
            }
        }

        if (channelFilePath.size() != 1){
            return error("当前自办节目选择的源文件符合格式的个数:"+channelFilePath.size()+",默认有且只有一个,请重新选择");
        }
        Iterator<String> iterator = channelFilePath.iterator();
        String firstFilePath = iterator.next();
        File file = new File(firstFilePath);
        if (file.exists()){
            String name = file.getName();
            if (!name.endsWith(upload_channel_file)){
                return error("当前自办节目选择的文件格式不正确!");
            }
        }
        logger.info("校验文件通过;"+firstFilePath);
        return success(file);
    }
//    public static final String upload_channel_file = ".ts";
    public static final String upload_channel_file = ".zip";

    /**
     * 递归查找指定目录及其子目录下的所有文件  统计上传文件总个数
     * @param directory 要查找的目录
     */
    public static Set<String> findFilesInSubdirectories(File directory,Set<String> channelFilePath) {
        // 检查目录是否存在且为目录
        if (directory.exists() && directory.isDirectory()) {
            // 获取目录下的所有文件和子目录
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isFile()) {
                        // 如果是文件，打印文件的绝对路径
//                        System.out.println("找到文件: " + file.getAbsolutePath());
//                        if (FileUploadUtils.isAllowedExtension(file.getName(), TaskConstans.synch_file_name)){
                        if (file.getName().endsWith(upload_channel_file)){
                            //将文件夹下的所有文件都复制上传
//                            count++;
                            channelFilePath.add(file.getAbsolutePath());
                        }
                    } else if (file.isDirectory()) {
                        // 如果是子目录，递归调用该方法
                        channelFilePath = findFilesInSubdirectories(file,channelFilePath);
                    }
                }
            }
        } else {
            System.out.println("指定的路径不是一个有效的目录。"+directory.getAbsolutePath());
        }
        return channelFilePath;
    }
    /**
     * 修改频道管理
     */
    @PreAuthorize("@ss.hasPermi('system:channel:edit')")
    @Log(title = "频道管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysChannelTemplate sysChannelTemplate)
    {


        if (!sysChannelTemplateService.checkNameUnique(sysChannelTemplate)){
            sysOperLogService.insertOperlogError("修改自办节目失败,频道:"+sysChannelTemplate.getName()+" ,该频道名称已存在");
            return error("修改自办节目失败,频道:"+sysChannelTemplate.getName()+" ,该频道名称已存在");
        }
        if (sysChannelTemplate.getUrlType().equals("2")){//网络
            if (!sysChannelTemplateService.checkSourceUrlUnique(sysChannelTemplate)){
                sysOperLogService.insertOperlogError("修改自办节目失败,频道:"+sysChannelTemplate.getName()+" ,该源地址已存在");
                return error("修改自办节目失败,频道:"+sysChannelTemplate.getName()+" ,该源地址已存在");
            }
        }

        String urlType = sysChannelTemplate.getUrlType();
        if (urlType.equals("1")){
            //U盘 ==>需要将选中的文件上传到nginx的指定位置
            List<String> sourcePath = sysChannelTemplate.getSourcePaths();
            AjaxResult ajaxResult = updateChannelFile(sysChannelTemplate);
            if (StringUtils.isNotNull(ajaxResult) && ajaxResult.isSuccess()){
                File channelFile = (File) ajaxResult.get(AjaxResult.DATA_TAG);
                //将文件上传到nginx的指定位置并入库
                String dataPath = File.separator+"channel_files"+File.separator+ DateUtils.dateTimeNow();
                String nginxPath = PlayControlConfig.getNginxRootPath()+dataPath+File.separator+channelFile.getName();
                String mappindPath = PlayControlConfig.getMappingPath()+dataPath+File.separator+channelFile.getName();
                FileUsingIO.moveFile(channelFile.getAbsolutePath(),nginxPath);
                sysChannelTemplate.setSourcePath(mappindPath);
                sysChannelTemplateService.updateSysChannelTemplate(sysChannelTemplate);
                sysOperLogService.insertOperlogSuccess("修改自办节目成功,频道名称:"+sysChannelTemplate.getName()+" ,源文件地址:"+sysChannelTemplate.getSourcePath()+" ,源输出方式:"+sysChannelTemplate.getSourceOut());

                SysChannelTemplate sqlChannel = sysChannelTemplateService.selectSysChannelTemplateById(sysChannelTemplate.getId());
                String sourcePathResult = sqlChannel.getSourcePath();
                if (StringUtils.isNotEmpty(sourcePathResult)){
                    String substring = sourcePathResult.substring(PlayControlConfig.getMappingPath().length());
                    String filePath = PlayControlConfig.getNginxRootPath()+substring;
                    File file = new File(filePath);
                    if (file.exists()){
                        file.delete();
                    }
                }

            }else{
                return ajaxResult;
            }

        }else if (urlType.equals("2")){
            SysChannelTemplate sqlChannel = sysChannelTemplateService.selectSysChannelTemplateById(sysChannelTemplate.getId());
            String sourcePathResult = sqlChannel.getSourcePath();
            if (StringUtils.isNotEmpty(sourcePathResult)){
                String substring = sourcePathResult.substring(PlayControlConfig.getMappingPath().length());
                String filePath = PlayControlConfig.getNginxRootPath()+substring;
                File file = new File(filePath);
                if (file.exists()){
                    file.delete();
                }
            }
            //网络
            sysChannelTemplateService.updateSysChannelTemplate(sysChannelTemplate);
            sysOperLogService.insertOperlogSuccess("修改自办节目成功,频道名称:"+sysChannelTemplate.getName()+" ,网络节目地址:"+sysChannelTemplate.getSourceUrl()+" ,源输出方式:"+sysChannelTemplate.getSourceOut());
        }
        return success();
    }

    @PutMapping("/changeChannelStatus")
    public AjaxResult changeChannelStatus(@RequestBody SysChannel sysChannel)
    {
        Long id = sysChannel.getId();
        String name = sysChannelService.selectSysChannelById(id,SysChannel.table_one).getName();
        sysOperLogService.insertOperlogSuccess("修改频道'"+name+"'状态成功");
        return toAjax(sysChannelService.updateSysChannel(sysChannel,SysChannel.table_one));
    }
    @Log(title = "自办节目", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        for (Long id : ids) {
            System.out.println("删除Id:"+id);
            SysChannelTemplate sysChannelTemplate = sysChannelTemplateService.selectSysChannelTemplateById(id);
            Long boardId = sysChannelTemplate.getBoardId();
            if (boardId != -1){
                return AjaxResult.error("该频道非自办节目,不允许进行删除");
            }
            String sourcePath = sysChannelTemplate.getSourcePath();
            if (StringUtils.isNotEmpty(sourcePath)){
                String substring = sourcePath.substring(PlayControlConfig.getMappingPath().length());
                String filePath = PlayControlConfig.getNginxRootPath()+substring;
                File file = new File(filePath);
                if (file.exists()){
                    boolean delete = file.delete();
                    System.out.println("删除流对应的源文件:"+delete);
                }
            }
            sysChannelTemplateService.deleteSysChannelTemplateById(id);
        }
        return success();
    }

}
